package com.example.wx_zl_gzh_demo.controller.web;


import com.example.wx_zl_gzh_demo.config.MessageConfig;
import com.example.wx_zl_gzh_demo.constant.EventConstant;
import com.example.wx_zl_gzh_demo.entity.message.Article;
import com.example.wx_zl_gzh_demo.entity.message.NewsMessage;
import com.example.wx_zl_gzh_demo.common.util.WordUtil;
import com.example.wx_zl_gzh_demo.service.WxService;
import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;

@RestController
public class WxController {
    @Autowired
    private MessageConfig messageConfig;

    @Autowired
    private WxService wxservice;

    @GetMapping("/")
    public String check(String signature,
                        String timestamp, String nonce, String echostr) throws NoSuchAlgorithmException {
//1)将token、timestamp、nonce三个参数进行字典序排序
        String token = "zhelu";
        List<String> list = Arrays.asList(token, timestamp, nonce);//排序
        Collections.sort(list);
//2)将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : list) {
            stringBuilder.append(s);
        }

        MessageDigest instance = MessageDigest.getInstance("sha1");//使用sha1进行加密，获得byte数组
        byte[] digest = instance.digest(stringBuilder.toString().getBytes());
        StringBuilder sum = new StringBuilder();
        for (byte b : digest) {
            sum.append(Integer.toHexString((b >> 4) & 15));
            sum.append(Integer.toHexString(b & 15));

//3)开发者获得加密后的字符串可与 signature 对比，标识该请求来源于微信
        }
        if (!StringUtils.isEmpty(signature) && signature.equals(sum.toString())) {
            return echostr;
        }
        return null;

    }

    @PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException, DocumentException {
        ServletInputStream inputStream = request.getInputStream();
        Map<String, Object> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        //读取request输入流,获取Document对象
        Document document = reader.read(inputStream);
        //获取root节点
        Element root = document.getRootElement();
        //获取所有的子节点
        List<Element> elements = root.elements();
        for (Element e : elements) {
            map.put(e.getName(), e.getStringValue());
        }
        System.out.println(map);
        String msgType = map.get("MsgType").toString();
        String message = "";
        switch (msgType) {
            case "text":
                //回复消息
                //图文回复
                if (messageConfig.getKeyword().equals(map.get("Content").toString())) {
                    message = getReplyNewsMessage(map);
                } else {
                    //同义词回复
                    message = getReplyMessage(map);
                }
                break;
            case "event":
                message=handleEvent(map);
                System.out.println(msgType);
                break;

            default:
                break;
        }

        return message;

    }
    /**
     * @param map:
     * @return String
     * @author Administrator
     * @description 处理事件推送
     * @date 2024/6/23 上午11:38
     */
    private String handleEvent(Map<String, Object> map) {
        String event = map.get("Event").toString();
        switch (event) {
            case "CLICK":
                if (String.valueOf(map.get("EventKey")).equals(String.valueOf(EventConstant.ONE_MENU_KEY_0))) {
                    String content = "你点击了eventkey是" + EventConstant.ONE_MENU_KEY_0 + "的按钮";
                    return  wxservice.getReplyTextMessage(map, content);

                }
                break;
            case "VIEW":
                System.out.println("view");
                break;
            default:break;
        }
        return null;
    }

    /**
     * @param map:
     * @return String
     * @author Administrator
     * @description 获取图文消息
     * @date 2024/6/21 下午4:26
     */
    private String getReplyNewsMessage(Map<String, Object> map) {
        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setFromUserName((String) map.get("ToUserName"));
        newsMessage.setToUserName((String) map.get("FromUserName"));
        newsMessage.setMsgType("news");
        newsMessage.setCreateTime(System.currentTimeMillis() / 1000);
        newsMessage.setArticleCount(1);

        ArrayList<Article> articles = new ArrayList<>();
        Article article = new Article();
        article.setTitle(messageConfig.getArticle().getTitle());
        article.setDescription(messageConfig.getArticle().getDescription());
        article.setUrl(messageConfig.getArticle().getUrl());
        article.setPicUrl(messageConfig.getArticle().getPicUrl());
        articles.add(article);
        newsMessage.setArticles(articles);
        //Xstream将java对象转化为xml字符串
        XStream xstream = new XStream();
        xstream.processAnnotations(NewsMessage.class);
        return xstream.toXML(newsMessage);
    }

    /**
     * @param map:
     * @return String
     * @author zhelu
     * @description 获取同义词信息
     * @date 2024/6/17 下午4:38
     */
    private String getReplyMessage(Map<String, Object> map) {
        String content = WordUtil.getWords((String) map.get("Content"));
        return  wxservice.getReplyTextMessage(map, content);
    }
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2024, 6, 25); // 假设今天是2024年6月25日

        // 计算距离周末还有多少天
        LocalDate nextWeekend = getNextWeekend(today);
        long daysToWeekend = ChronoUnit.DAYS.between(today, nextWeekend);
        System.out.println("距离【周末】还有" + daysToWeekend + "天");

        // 计算距离其他节日还有多少天（这里以中秋为例，需要您提供具体的中秋节日期）
        LocalDate midAutumnFestival = LocalDate.of(2024, 9, 29); // 假设2024年中秋节是9月29日
        long daysToMidAutumnFestival = ChronoUnit.DAYS.between(today, midAutumnFestival);
        System.out.println("距离【中秋】还有" + daysToMidAutumnFestival + "天");

        // ... 您可以继续添加其他节日的计算

        // 计算距离发工资的日子还有多少天（这里以1号发工资为例）
        LocalDate nextPayday = getNextPayday(today, 1);
        long daysToPayday = ChronoUnit.DAYS.between(today, nextPayday);
        System.out.println("距离【发工资】(1号)还有" + daysToPayday + "天");

        // ... 您可以继续添加其他发工资日期的计算

        // 计算距离退休还有多少天（这里以65岁退休为例，假设出生年份为1995年）
        int retirementAge = 65;
        int birthYear = 1995;
        LocalDate retirementDate = LocalDate.of(birthYear + retirementAge, 1, 1); // 假设退休日期为65岁生日的当年年初
        long daysToRetirement = ChronoUnit.DAYS.between(today, retirementDate);
        long yearsToRetirement = daysToRetirement / 365; // 简化为按年计算
        System.out.println("距离【退休】还有" + yearsToRetirement + "年(65岁退休)");
    }

    // 获取下一个周末的日期
    private static LocalDate getNextWeekend(LocalDate date) {
        int dayOfWeek = date.getDayOfWeek().getValue();
        int daysToAdd = (dayOfWeek == 1 || dayOfWeek == 7) ? 7 : 8 - dayOfWeek; // 如果是周末则加7天，否则加到下一个周末
        return date.plusDays(daysToAdd);
    }

    // 获取下一个发工资的日期（假设发工资日期为每月的指定日）
    private static LocalDate getNextPayday(LocalDate date, int dayOfMonth) {
        LocalDate nextPayday = date.withDayOfMonth(dayOfMonth);
        if (nextPayday.isBefore(date) || (nextPayday.getDayOfMonth() != dayOfMonth && date.getDayOfMonth() >= dayOfMonth)) {
            // 如果指定日期已经过去或者该月没有该日期（如2月30号），则取下个月的指定日期
            nextPayday = nextPayday.plusMonths(1);
        }
        return nextPayday;
    }
}